#include "main2.h"

#include "debug/SyntaxTreeOutput.h"

void main2 () {
	std::ofstream of;
	of.open("stablo_test.txt");

	std::ofstream ofSyntaxTree;
	ofSyntaxTree.open("syntaxTreeOutput.txt");
	SyntaxTreeOutput::write(*(CompilerData->SyntaxTree->RootNode), ofSyntaxTree);
	ofSyntaxTree.close();

	SemanticNodeProgram semanticNodeProgram(*(CompilerData->SyntaxTree->RootNode));
	of << semanticNodeProgram.toDebugString() << std::endl;
	of.close();
}

std::string flattenNamePeriodAdd(const SyntaxTreeNode& nameNode) {
	std::ostringstream ss;
	LexicUnit lu = CompilerData->Units->GetLexicUnit(nameNode.Nodes->GetData(0)->LexUnitID);
	ss << CompilerData->Units->GetLexicUnitString(&lu);
	for (int i = 0; i < nameNode.Nodes->GetData(1)->Nodes->GetCount(); i++) {
		lu = CompilerData->Units->GetLexicUnit(nameNode.Nodes->GetData(1)->Nodes->GetData(i)->Nodes->GetData(1)->LexUnitID);
		ss << "." << CompilerData->Units->GetLexicUnitString(&lu);
	}
	return ss.str();
}

std::string flattenTypeName(const SyntaxTreeNode &typeNode) {
	std::ostringstream ss;
	if (typeNode.Production == Gr_DataType__Name || typeNode.Production == Gr_DataType__Name_TemplateUse) {
		ss << flattenNamePeriodAdd(*typeNode.Nodes->GetData(0));
	} else {
	 LexicUnit lu = CompilerData->Units->GetLexicUnit(typeNode.Nodes->GetData(0)->LexUnitID);
	 ss << CompilerData->Units->GetLexicUnitString(&lu);
	}
	return ss.str();
}

std::vector<std::string> flattenTemplateIdentifiers(const SyntaxTreeNode &templateUseNode) {
	// also flattens <enum_names> node
	std::vector<std::string> result;
	result.push_back(CompilerData->Units->GetLexicUnitString(&CompilerData->Units->GetLexicUnit(templateUseNode.Nodes->GetData(0)->LexUnitID)));
	SyntaxTreeNode *Current = templateUseNode.Nodes->GetData(1);
	for (int x = 0; x < Current->Nodes->GetCount(); ++x) {
		result.push_back(CompilerData->Units->GetLexicUnitString(&CompilerData->Units->GetLexicUnit(Current->Nodes->GetData(x)->Nodes->GetData(1)->LexUnitID)));
	}
	return result;
}
/**
 *  @fn	SyntaxTreeNode* SemanticNodeExpression::copyNode(const SyntaxTreeNode *aNode, SyntaxTreeNode *parent = NULL)
 * 
 *  @brief	This method is here because SyntaxTreeNode has no copy constructor.
 * 
 *  @author	Nikola Novak.
 *  @date	6/15/2009.
 * 
 *  @param	aNode	Old node.
	*  @param parent Parent node.
 * 
 *  @return	A copy of an old node.
 */
SyntaxTreeNode *copyNode(const SyntaxTreeNode *aNode, SyntaxTreeNode *parent) {
	SyntaxTreeNode *res = new SyntaxTreeNode();
	res->LexUnitID = aNode->LexUnitID;
	res->Parent = parent;
	res->Production = aNode->Production;
	for (int x = 0; x < aNode->Nodes->GetCount(); ++x)
		res->Nodes->Add(copyNode(aNode->Nodes->GetData(x), res));
	return res;
}
/**
 *  @fn	bool main2::isValueNode(const SyntaxTreeNode *expressionNode)
 * 
 *  @brief	Checks if the node is a value node.
 * 
 *  @author	Nikola Novak.
 *  @date	6/16/2009.
 * 
 *  @param	expressionNode	A node.
 * 
 *  @return	True if node is a value node, otherwise false.
 */
bool isValueNode(const SyntaxTreeNode *expressionNode) {
	if (expressionNode->Production == Gr_Value__LITERAL ||
					expressionNode->Production == Gr_Value__Name_instance_of_Name ||
		   expressionNode->Production == Gr_Value__NAME_spLPar_Arguments_spRPar ||
					expressionNode->Production == Gr_Value__new_DataType_ArrayDefinitionsSize_Initialisation ||
					expressionNode->Production == Gr_Value__new_DataType_ArrayDefinitionsSize_spLPar_Arguments_spRPar ||
					expressionNode->Production == Gr_Value__spLPar_DataType_spRPar_VariableValue ||
					expressionNode->Production == Gr_Value__spLPar_Expression_spRPar ||
					expressionNode->Production == Gr_Value__VariableValue ||
					expressionNode->Production == Gr_Value__VariableValue_spPer_NAME_spLPar_Arguments_spRPar ||
					expressionNode->Production == Gr_Value__null) return true;
	return false;
}
